'use strict';

webappApp.factory('geo', ['geolocation', 'closeZoom', '$q', function (geolocation, closeZoom, $q) {
  return {
    radius: function (map) {
      var bounds = map.getBounds(),
          c = bounds.getCenter(),
          ne = bounds.getNorthEast(),
          d = google.maps.geometry.spherical.computeDistanceBetween(c, ne);
      return {
        center: c, 
        radius: d
      };
    },

    location: function () {
      var deferred = $q.defer();
      if (geolocation) {
        geolocation.getCurrentPosition(function (pos) {
          deferred.resolve({
            latitude: pos.coords.latitude,
            longitude: pos.coords.longitude
          });
        }, function (failure) {
          deferred.reject(failure);
        });
      } else {
        deferred.reject('Geolocation is not supported in this browser');
      }
      return deferred.promise;
    },

    panToUser: function (map, onIdle) {
      if (geolocation) {
        geolocation.getCurrentPosition(function (pos) {
          var coords = pos.coords;
          map.setCenter(new google.maps.LatLng(coords.latitude, coords.longitude));
          map.setZoom(closeZoom);
        });
      }
      google.maps.event.clearListeners(map, 'idle');
      if (onIdle) {
        google.maps.event.addListener(map, 'idle', onIdle);
      }
    },

    center: function (hasLocs) {
      var lat, lng, count = 0, p, loc;
      angular.forEach(hasLocs, function (hasLoc) {
        loc = hasLoc.location;
        if (loc) {
          count = count +1;
          lat = lat ? lat + loc.latitude : loc.latitude;
          lng = lng ? lng + loc.longitude : loc.longitude;
        }
      });
      return {
        latitude: lat / count,
        longitude: lng / count
      };
    },

    bounds: function (hasLocs) {
      var minLat = 90, minLng = 180, maxLat = -90, maxLng = -180, l;
      if (!hasLocs || hasLocs.length) {
        minLat = minLat * -1;
        minLng = minLng * -1;
        maxLat = maxLat * -1;
        maxLng = maxLng * -1;
      }
      angular.forEach(hasLocs, function (hasLoc) {
        l = hasLoc.location;
        minLat = Math.min(minLat, l.latitude);
        minLng = Math.min(minLng, l.longitude);
        maxLat = Math.max(maxLat, l.latitude);
        maxLng = Math.max(maxLng, l.longitude);
      });
      return new google.maps.LatLngBounds(
        new google.maps.LatLng(
          minLat,
          minLng
        ),
        new google.maps.LatLng(
          maxLat,
          maxLng
        )
      );
    }
  };
}])
.constant('closeZoom', 19)
.factory('geolocation', function ($window) {
  if ($window.navigator) return $window.navigator.geolocation;
});